package Thread;
/**1，构成死锁的场景
 * a)一个线程一把锁->可重入锁
 * b)两个线程两把锁->两个线程对锁的等待过程形成的循环
 * c)N个线程M把锁，->哲学家就餐问题
 * 2.死锁的四个必要条件
 * a)互斥
 * b)不可剥夺
 * c)请求和保持
 * d)循环等待
 * 3.如何避免死锁
 * 打破c->把嵌套的锁改为并列的锁
 * 打破d->对锁的顺序进行约定
* */
public class Demo20 {
    public static void main(String[] args) throws InterruptedException {
        Object locker1 = new Object();
        Object locker2 = new Object();
        Thread t1 =new Thread(()->{
            synchronized (locker1) { //两个线程竞争锁，形成死锁
                try {
                    Thread.sleep(1000); //如果不加sleep可能不会阻塞形成死锁，t1可能一口气拿到locker1和locker2
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (locker2) {
                    System.out.println("线程1两个线程");
                }
            }
        });
        Thread t2 =new Thread(()->{
            synchronized (locker2) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                synchronized (locker1) {
                    System.out.println("线程2两个线程");
                }
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}
